home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine CD 1995 / Archive Magazine CD 1995.iso / discs / prog_disc / volume_1 / issue_11 / robbins / maclib / floatops (.txt)
Encoding:
RISC OS BBC BASIC V Source  |  1995-06-13  |  21.5 KB  |  657 lines

  1.  > MACLIB.FloatOps
  2.  *********************************************************************
  3.  *           FLOATING POINT INSTRUCTION ASSEMBLY FUNCTION            *
  4.  *                                                                   *
  5.  *              (C) Copyright K G Robbins 14 June 1988               *
  6.  *                                                                   *
  7.  *  This function accepts a floating point instruction as an input   *
  8.  *  string and assembles the corresponding instruction word.         *
  9.  *  All seven distinguishable instruction formats are recognised.    *
  10.  *                                                                   *
  11.  *  The function expects a valid assembler pass number in global     *
  12.  *  integer variable Pass%                                           *
  13.  *                                                                   *
  14.  *  The function destroys static variables I%, J%, S%, T%, Z%        *
  15.  *********************************************************************
  16. flop(Inst$)
  17. FPError:
  18. FPAssem(-1,""): =0
  19. IF0=0:F1=1:F2=2:F3=3:F4=4:F5=5:F6=6:F7=7   :
  20.  default float registers.
  21. KR0=0:R1=1:R2=2:R3=3:R4=4:R5=5:R6=6:R7=7   :
  22.  default general registers.
  23. 7R8=8:R9=9:R10=10:R11=11:R12=12:R13=13:R14=14:R15=15
  24. JInst$+=" "                           :
  25.  add a blank to terminate scan.
  26.  *********************************************************************
  27.  *  Here we build the instruction code, with the operation code and  *
  28.  *  appropriate operand, precision and rounding references.          *
  29.  *********************************************************************
  30. >S%=1:
  31. Deblank<>0 
  32.  212,"" :
  33.  scan past leading blanks.
  34. Inst$,S%,3) 
  35.  "MVF":I%=&0E008100:
  36. Format1
  37.  "MNF":I%=&0E108100:
  38. Format1
  39.  "ABS":I%=&0E208100:
  40. Format1
  41.  "RND":I%=&0E308100:
  42. Format1
  43.  "SQT":I%=&0E408100:
  44. Format1
  45.  "LOG":I%=&0E508100:
  46. Format1
  47.  "LGN":I%=&0E608100:
  48. Format1
  49.  "EXP":I%=&0E708100:
  50. Format1
  51.  "SIN":I%=&0E808100:
  52. Format1
  53.  "COS":I%=&0E908100:
  54. Format1
  55.  "TAN":I%=&0EA08100:
  56. Format1
  57.  "ASN":I%=&0EB08100:
  58. Format1
  59.  "ACS":I%=&0EC08100:
  60. Format1
  61.  "ATN":I%=&0ED08100:
  62. Format1
  63.  "ADF":I%=&0E000100:
  64. Format2
  65.  "MUF":I%=&0E100100:
  66. Format2
  67.  "SUF":I%=&0E200100:
  68. Format2
  69.  "RSF":I%=&0E300100:
  70. Format2
  71.  "DVF":I%=&0E400100:
  72. Format2
  73.  "RDF":I%=&0E500100:
  74. Format2
  75.  "POW":I%=&0E600100:
  76. Format2
  77.  "RPW":I%=&0E700100:
  78. Format2
  79.  "RMF":I%=&0E800100:
  80. Format2
  81.  "FML":I%=&0E900100:
  82. Format2
  83.  "FDV":I%=&0EA00100:
  84. Format2
  85.  "FRD":I%=&0EB00100:
  86. Format2
  87.  "POL":I%=&0EC00100:
  88. Format2
  89.  "LDF":I%=&0C100100:
  90. Format3
  91.  "STF":I%=&0C000100:
  92. Format3
  93.  "CMF":I%=&0E90F110:
  94. Format4
  95.  "CNF":I%=&0EB0F110:
  96. Format4
  97.  "FLT":I%=&0E000110:
  98. Format5
  99.  "FIX":I%=&0E100110:
  100. Format6
  101.  "WFS":I%=&0E200110:
  102. Format7
  103.  "RFS":I%=&0E300110:
  104. Format7
  105.  "WFC":I%=&0E400110:
  106. Format7
  107.  "RFC":I%=&0E500110:
  108. Format7
  109.  200,""
  110. FPAssem(I%,Inst$): 
  111.  *********************************************************************
  112.  *             Here we process a format 1 instruction                *
  113.  *    (Format 1) Unary ops  -- op<cond>prec<round> Fd,{Fm|#val}      *
  114.  *********************************************************************
  115. Format1
  116. JAS%+=3:I%+=
  117. Cond+
  118. Prec1+
  119. Round1    :
  120.  insert opcode modifiers.
  121. Inst$,S%,1)<>" " 
  122.  202,""
  123. Deblank=0 
  124.  S%-=1 
  125.  213,"" :
  126.  scan past excess blanks.
  127. MGI%+=(
  128. FPReg)<<12                    :
  129.  insert destination register.
  130.  T%<>1 
  131.  201,""
  132. Inst$,S%+1,1)="#" 
  133.  I%+=
  134. Literal 
  135.  I%+=
  136. FPReg
  137.  T%>0 
  138.  201,""
  139.  *********************************************************************
  140.  *             Here we process a format 2 instruction                *
  141.  *    (Format 2) Binary ops -- op<cond>prec<round> Fd,Fn,{Fm|#val}   *
  142.  *********************************************************************
  143. Format2
  144. WAS%+=3:I%+=
  145. Cond+
  146. Prec1+
  147. Round1    :
  148.  insert opcode modifiers.
  149. Inst$,S%,1)<>" " 
  150.  202,""
  151. Deblank=0 
  152.  S%-=1 
  153.  213,"" :
  154.  scan past excess blanks.
  155. ZGI%+=(
  156. FPReg)<<12                    :
  157.  insert destination register.
  158.  T%<>1 
  159.  201,""
  160. \?I%+=(
  161. FPReg)<<16                    :
  162.  insert LHS register.
  163.  T%<>1 
  164.  201,""
  165. Inst$,S%+1,1)="#" 
  166.  I%+=
  167. Literal 
  168.  I%+=
  169. FPReg
  170.  T%>0 
  171.  201,""
  172.  *********************************************************************
  173.  *             Here we process a format 3 instruction                *
  174.  *      (Format 3) Data transfer ops -- op<cond>prec Fd,addr         *
  175.  *********************************************************************
  176. Format3
  177. fBS%+=3:I%+=
  178. Cond+
  179. Prec3             :
  180.  insert opcode modifiers.
  181. Inst$,S%,1)<>" " 
  182.  202,""
  183. Deblank=0 
  184.  S%-=1 
  185.  213,"" :
  186.  scan past excess blanks.
  187. iGI%+=(
  188. FPReg)<<12                    :
  189.  insert destination register.
  190.  T%<>1 
  191.  201,""
  192. Inst$,S%+1,1)="[" 
  193.  *******************************************************************
  194.  * Here we handle an explicit address- [Rn,#Off]<!> or [Rn]<,#Off> *
  195.  *******************************************************************
  196. o@  S%+=1:I%+=(
  197. GPReg)<<16            :
  198.  insert base register.
  199.  T%<1 
  200.  204,""
  201.  T%=2 
  202. rK    
  203.  *****************************************************************
  204. sK    
  205.  * Only one parameter in the brackets - post-indexed mode.       *
  206. tK    
  207.  *****************************************************************
  208. u>    S%+=1                            :
  209.  step past the "]".
  210. Inst$,S%,1) 
  211. wF      
  212.  " ":I%+=&00800000         :
  213.  insert post-indexed offset 0.
  214. xC      
  215.  ",":I%+=
  216. Offset          :
  217.  insert post-indexed offset.
  218.       
  219.  205,""
  220.       
  221.  T%>0 
  222.  201,""
  223. {        
  224. }K    
  225.  *****************************************************************
  226. ~K    
  227.  * Multiple parameters in the brackets - pre-indexed mode.       *
  228. K    
  229.  *****************************************************************
  230. E    I%+=
  231. Offset+&01000000           :
  232.  insert pre-indexed offset.
  233.  T%<>2 
  234.  204,""
  235. Inst$,S%+1,1) 
  236. E      
  237.  " ":                       
  238.  all done if blank after "]".
  239. ?      
  240.  "!": I%+=&00200000        :
  241.  insert Writeback flag.
  242.       
  243.  206,""
  244.         
  245.  *******************************************************************
  246.  * Here we handle a label expression. The user must ensure that    *
  247.  * the net relocatability is 1; we have no way of checking it.     *
  248.  *******************************************************************
  249. H  I%+=&010F0000                      :
  250.  use R15 as pre-indexed base.
  251. &  Z%=S%+1:
  252. Dlimiter>0 
  253.  201,""
  254. *  J%=(
  255. Inst$,Z%,S%-Z%)))-(P%+8))/4
  256. (J%)>255 
  257.  207,""
  258.  J%<0 
  259.  I%+=
  260. (J%) 
  261.  I%+=J%+&00800000
  262.  *********************************************************************
  263.  *             Here we process a format 4 instruction                *
  264.  *  We enter having recognised the basic opcode - CMF or CNF. First  *
  265.  *  we test if the opcode has the exception modifier (CMFE or CNFE)  *
  266.  *  and adjust the instruction skeleton accordingly.                 *
  267.  *     (Format 4) Status transfer ops -- op<cond> Fn,{Fm|#val}       *
  268.  *********************************************************************
  269. Format4
  270. Inst$,S%+3,1)="E" 
  271. Inst$,S%+4,1)<>"Q" 
  272.  I%+=&00400000:S%+=4 
  273.  S%+=3
  274. CI%+=
  275. Cond                           :
  276.  insert opcode modifiers.
  277. Inst$,S%,1)<>" " 
  278.  202,""
  279. Deblank=0 
  280.  S%-=1 
  281.  213,"" :
  282.  scan past excess blanks.
  283. ?I%+=(
  284. FPReg)<<16                    :
  285.  insert LHS register.
  286.  T%<>1 
  287.  201,""
  288. Inst$,S%+1,1)="#" 
  289.  I%+=
  290. Literal 
  291.  I%+=
  292. FPReg
  293.  T%>0 
  294.  201,""
  295.  *********************************************************************
  296.  *             Here we process a format 5 instruction                *
  297.  *    (Format 5) GP reg xfr -- op<cond>prec<round> Fn,Rd             *
  298.  *********************************************************************
  299. Format5
  300. AS%+=3:I%+=
  301. Cond+
  302. Prec1+
  303. Round1    :
  304.  insert opcode modifiers.
  305. Inst$,S%,1)<>" " 
  306.  202,""
  307. Deblank=0 
  308.  S%-=1 
  309.  213,"" :
  310.  scan past excess blanks.
  311. GI%+=(
  312. FPReg)<<16                    :
  313.  insert destination register.
  314.  T%<>1 
  315.  201,""
  316. GPReg<<12
  317.  T%>0 
  318.  201,""
  319.  *********************************************************************
  320.  *             Here we process a format 6 instruction                *
  321.  *    (Format 6) GP reg xfr -- op<cond>prec<round> Rd,Fm             *
  322.  *********************************************************************
  323. Format6
  324. AS%+=3:I%+=
  325. Cond+
  326. Prec1+
  327. Round1    :
  328.  insert opcode modifiers.
  329. Inst$,S%,1)<>" " 
  330.  202,""
  331. Deblank=0 
  332.  S%-=1 
  333.  213,"" :
  334.  scan past excess blanks.
  335. GI%+=(
  336. GPReg)<<12                    :
  337.  insert destination register.
  338.  T%<>1 
  339.  201,""
  340. BI%+=
  341. FPReg                          :
  342.  insert source register.
  343.  T%>0 
  344.  201,""
  345.  *********************************************************************
  346.  *             Here we process a format 7 instruction                *
  347.  *    (Format 7) GP reg xfr -- op<cond> Rd                           *
  348.  *********************************************************************
  349. Format7
  350. CS%+=3:I%+=
  351. Cond                     :
  352.  insert opcode modifiers.
  353. Inst$,S%,1)<>" " 
  354.  202,""
  355. Deblank=0 
  356.  S%-=1 
  357.  213,"" :
  358.  scan past excess blanks.
  359. GI%+=(
  360. GPReg)<<12                    :
  361.  insert destination register.
  362.  T%>0 
  363.  201,""
  364.  *********************************************************************
  365.  *    Here we scan the instruction string for the next non-blank.    *
  366.  *  At entry S% points to the current character, updated at exit.    *
  367.  *  The function sets a completion code -                            *
  368.  *      0 - positioned at non-blank     -1 - no non-blank found      *
  369.  *********************************************************************
  370. Deblank
  371.  S%=S% 
  372. (Inst$)
  373. Inst$,S%,1)<>" " 
  374.  *********************************************************************
  375.  *    Here we scan the instruction string for the next delimiter.    *
  376.  *  At entry S% points to the leading delimiter, updated at exit.    *
  377.  *  The function sets a completion code identifying the delimiter -  *
  378.  *    0 - blank   1 - comma   2 - right bracket   -1 - none found    *
  379.  *********************************************************************
  380. Dlimiter
  381.  S%=S%+1 
  382. (Inst$)
  383. Inst$,S%,1) 
  384.  " ":=0
  385.  ",":=1
  386.  "]":=2
  387.  *********************************************************************
  388.  *  Here we evaluate the next operand as a general purpose register. *
  389.  *********************************************************************
  390. GPReg
  391. FZ%=S%+1:T%=
  392. Dlimiter                :
  393.  scan out the base register.
  394. Inst$,Z%,S%-Z%))        :
  395.  evaluate register number.
  396.  J%<0 
  397.  J%>15 
  398.  203,""
  399.  *********************************************************************
  400.  *  Here we evaluate the next operand as a floating point register.  *
  401.  *********************************************************************
  402. FPReg
  403. *Z%=S%+1: T%=
  404. Dlimiter: 
  405.  T%>1 
  406.  201,""
  407. Inst$,Z%,S%-Z%))        :
  408.  evaluate register number.
  409.  J%<0 
  410.  J%>7 
  411.  208,""
  412.  *********************************************************************
  413.  *  Here we evaluate the next operand as an offset from a base reg.  *
  414.  *********************************************************************
  415. Offset
  416. Inst$,S%+1,1)<>"#" 
  417.  205,""
  418. ,Z%=S%+2: T%=
  419. Dlimiter: 
  420.  T%=1 
  421.  201,""
  422. Inst$,Z%,S%-Z%))/4
  423. (J%)>255 
  424.  207,""
  425.  J%<0 
  426. (J%) 
  427.  =J%+&00800000
  428.  *********************************************************************
  429.  *       Here we evaluate the next operand as a literal value.       *
  430.  *********************************************************************
  431. Literal
  432. ,Z%=S%+2: T%=
  433. Dlimiter: 
  434.  T%>0 
  435.  201,""
  436. Inst$,Z%,S%-Z%)) 
  437.  0.5:=&0000000E
  438.  0:=&00000008
  439.  1:=&00000009
  440.  2:=&0000000A
  441.  3:=&0000000B
  442.  4:=&0000000C
  443.  5:=&0000000D
  444.  10:=&0000000F
  445.  209,""
  446.  *********************************************************************
  447.  *  Here we process the execution condition for the instruction.     *
  448.  *********************************************************************
  449. Inst$,S%,2) 
  450.  "EQ":S%+=2:=&00000000
  451.  "NE":S%+=2:=&10000000
  452.  "CS":S%+=2:=&20000000
  453.  "CC":S%+=2:=&30000000
  454.  "MI":S%+=2:=&40000000
  455.  "PL":S%+=2:=&50000000
  456.  "VS":S%+=2:=&60000000
  457.  "VC":S%+=2:=&70000000
  458.  "HI":S%+=2:=&80000000
  459.  "LS":S%+=2:=&90000000
  460.  "GE":S%+=2:=&A0000000
  461.  "LT":S%+=2:=&B0000000
  462.  "GT":S%+=2:=&C0000000
  463.  "LE":S%+=2:=&D0000000
  464.  "AL":S%+=2:=&E0000000
  465.  "NV":S%+=2:=&F0000000
  466.  =&E0000000               :
  467.  must be precision/round.
  468.  *********************************************************************
  469.  * Here we process precision for format 1,2,5,6,7 (set in bits 19,7) *
  470.  *********************************************************************
  471. Prec1
  472. Inst$,S%,1) 
  473.  "S":S%+=1:=&00000000
  474.  "D":S%+=1:=&00000080
  475.  "E":S%+=1:=&00080000
  476.  210,""
  477.  *********************************************************************
  478.  *    Here we process precision for format 3 (set in bits 22,15)     *
  479.  *********************************************************************
  480. Prec3
  481. Inst$,S%,1) 
  482.  "S":S%+=1:=&00000000
  483.  "D":S%+=1:=&00008000
  484.  "E":S%+=1:=&00400000
  485.  "P":S%+=1:=&00408000
  486.  210,""
  487.  *********************************************************************
  488.  *  Here we process rounding for format 1 and 2 (flags in bits 6,5)  *
  489.  *********************************************************************
  490. Round1
  491. Inst$,S%,1) 
  492.  " ":=&00000000
  493.  "P":S%+=1:=&00000020
  494.  "M":S%+=1:=&00000040
  495.  "Z":S%+=1:=&00000060
  496.  211,""
  497.  *********************************************************************
  498.  *        Here we output the assembled instruction or constant.      *
  499.  *  The options selected in Pass% direct the output and any listing. *
  500.  *  Output is always directed to storage at a 4-byte boundary, the   *
  501.  *  location counters being adjusted beforehand if necessary.        *
  502.  *                                                                   *
  503.  *  Parameter I% is the 4-byte word to be output to the code space   *
  504.  *               at the current location counter.                    *
  505.  *                                                                   *
  506.  *  Parameter I$ is a string to be printed in the operation code     *
  507.  *               field of the output listing. (This is generally     *
  508.  *               the instruction string that has been processed.)    *
  509.  *                                                                   *
  510.  *  The function destroys static variable Z%                         *
  511.  *********************************************************************
  512. FPAssem(I%,I$)
  513. Z%=P% 
  514.  Z%<>0 
  515. UG  Z%=4-Z%                                :
  516.  find adjustment factor.
  517. VC  P%+=Z%:
  518.  (Pass% 
  519.  O%+=Z%    :
  520.  align to 4-byte boundary.
  521.  (Pass% 
  522. "00000000"+
  523. ~(P%),8);" ";
  524. "00000000"+
  525. ~(I%),8);" +++++++++ ";I$
  526.  (Pass% 
  527.  *******************************************************************
  528.  * Output the assembled word in offset assembly mode.              *
  529.  *******************************************************************
  530. ]J  !(O%)=I%                               :
  531.  output the assembled word.
  532. ^I  O%+=4:P%+=4                            :
  533.  update location counters.
  534.  *******************************************************************
  535.  * Output the assembled word in direct assembly mode.              *
  536.  *******************************************************************
  537. cJ  !(P%)=I%                               :
  538.  output the assembled word.
  539. dH  P%+=4                                  :
  540.  update location counter.
  541.  *********************************************************************
  542.  *  Here we log out trapped assembly errors                          *
  543.  *********************************************************************
  544. FPError
  545.  Msg$
  546.  200: Msg$="Error 200: Invalid Opcode"
  547.  201: Msg$="Error 201: Invalid delimiter"
  548.  202: Msg$="Error 202: Unexpected opcode modifier"
  549.  203: Msg$="Error 203: Invalid general register"
  550.  204: Msg$="Error 204: Invalid address reference"
  551.  205: Msg$="Error 205: Invalid offset field"
  552.  206: Msg$="Error 206: Invalid writeback flag"
  553.  207: Msg$="Error 207: Invalid offset value"
  554.  208: Msg$="Error 208: Invalid floating point register"
  555.  209: Msg$="Error 209: Invalid literal value"
  556.  210: Msg$="Error 210: Invalid precision specification"
  557.  211: Msg$="Error 211: Invalid rounding specification"
  558.  212: Msg$="Error 212: No Opcode found"
  559.  213: Msg$="Error 213: No Operands found"
  560.  220: Msg$="Error 220: Short float conversion underflow"
  561.  " at line ";
  562.  (Pass% 
  563.  Msg$
  564.  *********************************************************************
  565.  *             FLOATING POINT CONSTANT ASSEMBLY FUNCTION             *
  566.  *                                                                   *
  567.  *              (C) Copyright K G Robbins 14 June 1988               *
  568.  *                                                                   *
  569.  *  This function accepts a floating point number in ARM Basic       *
  570.  *  format and maps it into IEEE single-length format. The actual    *
  571.  *  parameter may be entered as a literal or as an expression; this  *
  572.  *  will be evaluated by the Basic interpreter before presentation   *
  573.  *  as the formal parameter.                                         *
  574.  *                                                                   *
  575.  *  The function expects a valid assembler pass number in global     *
  576.  *  integer variable Pass%                                           *
  577.  *                                                                   *
  578.  *  The function destroys static variables I%, J%, S%                *
  579.  *********************************************************************
  580. equfS(K)
  581. FPError:
  582. FPAssem(-1,""): =0
  583.  (Pass% 
  584.  S%=O% 
  585.  S%=P%   :
  586.  use output area as worksp.
  587.  *********************************************************************
  588.  *  We use the code space as a workspace to remap the input number.  *
  589.  *********************************************************************
  590. E|(S%+4)=K                                :
  591.  pick up the argument.
  592. FI%=!(S%+4)                               :
  593.  pick up ARMB mantissa.
  594. FJ%=?(S%+8)                               :
  595.  pick up ARMB exponent.
  596.  J%<>0 
  597.  I%<>0 
  598. I  I%=(I% >> 8) 
  599.  &807FFFFF             :
  600.  cnvt ARMB mantissa to IEEE.
  601. K  J%+=(127-128-1)                        :
  602.  cnvt ARMB exponent to IEEE.
  603.  J%<=0 
  604.  220,""             :
  605.  would be a NAN.
  606. H  I%+=(J%<<23)                           :
  607.  build IEEE float number.
  608. FPAssem(I%,"EQUFS "+
  609. (K)): 
  610.  *********************************************************************
  611.  *             FLOATING POINT CONSTANT ASSEMBLY FUNCTION             *
  612.  *                                                                   *
  613.  *              (C) Copyright K G Robbins 14 June 1988               *
  614.  *                                                                   *
  615.  *  This function accepts a floating point number in ARM Basic       *
  616.  *  format and maps it into IEEE double-length format. The actual    *
  617.  *  parameter may be entered as a literal or as an expression; this  *
  618.  *  will be evaluated by the Basic interpreter before presentation   *
  619.  *  as the formal parameter.                                         *
  620.  *                                                                   *
  621.  *  The function expects a valid assembler pass number in global     *
  622.  *  integer variable Pass%                                           *
  623.  *                                                                   *
  624.  *  The function destroys static variables I%, J%, S%                *
  625.  *********************************************************************
  626. equfD(K)
  627. FPError:
  628. FPAssem(-1,""):
  629. FPAssem(-1,""): =0
  630.  (Pass% 
  631.  S%=O% 
  632.  S%=P%   :
  633.  use output area as worksp.
  634.  *********************************************************************
  635.  *  We use the code space as a workspace to remap the input number.  *
  636.  *********************************************************************
  637. E|(S%+4)=K                                :
  638.  pick up the argument.
  639. FI%=!(S%+4)                               :
  640.  pick up ARMB mantissa.
  641. FJ%=?(S%+8)                               :
  642.  pick up ARMB exponent.
  643.  J%<>0 
  644.  I%<>0 
  645. I  I%=(I% >> 11) 
  646.  &800FFFFF            :
  647.  cnvt ARMB mantissa to IEEE.
  648. K  J%+=(1023-128-1)                       :
  649.  cnvt ARMB exponent to IEEE.
  650. H  I%+=(J%<<20)                           :
  651.  build IEEE float number.
  652. J  J%=(!(S%+4) << 21)                     :
  653.  align residue of mantissa.
  654. FPAssem(I%,"EQUFD "+
  655. (K)):
  656. FPAssem(J%,""): 
  657.